import JQuery from 'jquery';
let TaskQueue = function() {
    let _this = this;
    this.running = false;
    this.executeFun = null;
    this.stopFun = null;
    this.changeTaskFun = null;
    let queue = [];
    let runningIndex = -1;
    this.getQueue = function() { // 获取队列文件个数
        return queue;
    };
    this.addTask = function(obj) { // 添加任务添加上传列表
        queue.push(obj);
        if (this.changeTaskFun) {
            this.changeTaskFun(this);
        } // 添加任务后上传列表数量变更
        return this;
    };
    this.removeTask = function(obj, startIndex) { // 删除任务 上传完成后自动删除
        if (startIndex == null || startIndex == undefined) {
            startIndex = 0;
        }
        let obj1 = null;
        let index = -2;
        let ls = [];
        for (let i = 0; i < queue.length; i++) {
            if (queue[i] != obj) {
                ls.push(queue[i]);
            } else {
                obj1 = obj;
                index = i;
            }
        }
        queue = ls; // 删除后的重新调整队列
        if (obj1 && runningIndex == index) {
            if (this.stopFun) { // 停止之后的方法回调
                this.stopFun(obj1, true);
            }
            this.running = false;
            this.execute(startIndex); // 执行下个队列
        } else if (obj1 && this.stopFun) {
            this.stopFun(obj1, false);
        }
        if (this.changeTaskFun) { // 更改任务
            this.changeTaskFun(this);
        }
        return obj1; // 返回最终的任务
    };
    this.removeTaskAt = function(index, startIndex) { // 重新调整队列
        let obj = null;
        if (index >= 0 && index < queue.length) {
            obj = this.removeTask(queue[index], startIndex);
        }
        return obj;
    };
    this.execute = function(index) {
        if (queue.length && this.executeFun && this.running == false && index >= 0 && index < queue.length) {
            this.running = true;
            this.executeFun(queue[index]); // 上传队列里面的第几个文件
            runningIndex = index;
        }
    };
    this.getRunIndex = function() {
        return runningIndex;
    };
};

let MultiPartUpload = function() {
    let _this = this;
    let file = null; // 默认定义文件为null
    this.url = null;// 请求的url数组0、获取文件已上传的大小1、上传地址
    this.fileSize = 0;// 文件大小
    this.start = 0;// 上传起始位置
    this.end = 0;// 上传终止位置
    let state = true;
    let finish = true;
    let uploadError = false;
    let timer = null;
    this.limit = 1024 * 1024;// 每次上传的文件块大小
    this.minLimit = 1024 * 100;// 最小每次上传的文件块大小
    this.maxLimit = 1024 * 1024 * 100;// 最大每次上传的文件块大小
    this.maxFile = 524288000;// 允许上传的最大文件大小，默认200mb
    this.param = [{}, {}];// 自定义参数
    this.autoSpeed = false;// 是否自动计算每次上传的文件块大小
    this.beforeFun = null;// 上传之前函数
    this.successFun = null;// 上传成功的回调函数
    this.finishFun = null;// 上传完毕的回调函数
    this.errorFun = null;// 上传失败的回调函数
    this.executeTime = 0;// 每次上传的执行时间（毫秒）
    this.waitTime = 1000;// 每次上传的等待时间，如果不在这个时间的正负10%范围内，系统自动计算上传的文件块大小
    this.failtimeout = 300000;// 失败超时时间（毫秒）
    this.running = false; // 是否执行上传中
    this.successCode = '1'; // 文件上传成功状态码
    this.name = ''; // 默认名字
    this.formData = null; // 默认参数格式
    let startTime = 0; // 开始时间
    let finishSize = 0; // 完成大小
    let senderror = false; // 失败状态
    let timestamp = 0; // 默认标记时间戳
    let lasttimestamp = 0; // 最后时间戳
    function _init () { // 初始方法
        _this.start = 0; // 开始大小
        _this.end = _this.limit; // 文件截止点为每次文件块大小
        if (_this.end > _this.fileSize) {
            _this.end = _this.fileSize;
        } // 如果文件截止大小大于文件大小，则文件的截止大小为文件的大小，不再进行文件拆分
    }
    this.getStartTime = function() { // 开始时间为默认开始时间 0
        return startTime;
    }
    this.getFinishSize = function() { // 上传完成大小为完成大小
        return finishSize;
    }
    this.setFile = function(f) { // 设置文件对象， 名字、大小，判断文件大小是否符合要求
        file = f;
        this.name = file.name;
        this.fileSize = file.size;
        if (this.maxFile < this.fileSize) {
            return false;
        } else {
            return true;
        } // 如果 文件大于200mb则返回fales
    };
    this.isFinish = function() { // 是否完成，根据文件小于等于终止位置返回 布尔值
        return this.fileSize <= this.end;
    };
    this.isStop = function() { // 是否停止
        return finish;
    };
    function getParam () { // 设置参数
        if (_this.paramFun) {
            return _this.paramFun();
        } else {
            return null;
        }
    }
    this.getStart = function(response) { //  开始
        let start = 0;
        try {
            start = parseInt(response.body.message);
        } catch (e) { }
        return start;
    };
    this.getUploadFlag = function(response) { // 上传完成回调方法
        let mess = '0';
        try {
            mess = response.body.message;
        } catch (e) { }
        return mess;
    };
    this.stop = function() { // 结束
        finish = true;
    };
    this.upload = function() { // 上传
        this.running = true;
        startTime = Date.now(); // 时间戳
        finishSize = 0;
        let param = getParam();
        if (param && param[0]) { // 设置参数 目前参数为token
            for (let key in param[0]) {
                this.param[0][key] = param[0][key];
            }
        }
        if (file && finish) { // 文件存在 根据flag来判断是否能够上传 ？？
            finish = false;
            _init(); // 获取end值
            let data = {
                filename: file.name,
                size: this.fileSize
            };
            if (this.param[0]) { // 设置参数 目前只有token
                for (let key in _this.param[0]) {
                    data[key] = this.param[0][key];
                }
            }
            if (this.url[0]) { // 可以设置进度条并上传文件
                JQuery.ajax({
                    url: this.url[0],
                    type: 'POST',
                    data: data,
                    dataType: "json",
                    success: function(responseText) {
                        _this.start = _this.getStart(responseText); // 获取上传文件起始点 or 该文件在服务器上存储的大小
                        if (_this.start >= _this.fileSize) { // 如果开始本次开始的块大小大于等于本次文件拆分的大小
                            _this.start = _this.fileSize - 1; // 担心文件缺失
                        }
                        if (_this.limit > _this.maxLimit) {
                            _this.limit = _this.maxLimit;
                        }
                        if (_this.limit < _this.minLimit) {
                            _this.limit = _this.minLimit;
                        }
                        _this.end = _this.start + _this.limit <= _this.fileSize ? _this.start + _this.limit : _this.fileSize;
                        if (_this.start < _this.fileSize) { // 如果开始本次开始的块大小 小于 本次文件拆分的大小
                            _upload();
                            timer && window.clearInterval(timer);
                            timer = null;
                            timer = window.setInterval(function() {
                                _upload();
                            }, 100); // 间隔100毫秒循环调
                        } else { // 添加其他特殊接口返回错误
                            finish = true;
                            if (_this.finishFun) { // 结束上传 清除队列
                                _this.finishFun(_this);
                            }
                        }
                    },
                    error: function(responseText) { // 没有返回正确的状态
                        finish = true;
                    }
                });
            } else { // 仅上传文件
                _upload();
                timer && window.clearInterval(timer);
                timer = null;
                timer = window.setInterval(function() {
                    _upload();
                }, 100);
            }
        }
    };
    function _upload () {
        if (finish && state) {
            _this.running = false; // 不再执行
            window.clearInterval(timer); // 清除定时器
            timer = null;
            if (uploadError) {
                if (_this.errorFun) {
                    _this.errorFun(_this);
                }
            } else {
                if (_this.finishFun) {
                    _this.finishFun(_this);
                }
            }
        } else if (state) {
            state = false;
            _this.response = null;
            let param = getParam();
            if (param && param[1]) { // 目前token
                for (let key in param[1]) {
                    _this.param[1][key] = param[1][key];
                }
            }
            let datetime = Date.now(); // 新的时间戳
            if (!senderror) {
                lasttimestamp = datetime; // 最后的时间戳 == 新的时间戳
                if (_this.limit > _this.maxLimit) { // 每次块大小 大于 最大块大小
                    _this.limit = _this.maxLimit; // 每次块大小则等与最大块大小
                }
                if (_this.limit < _this.minLimit) { // 每次块大小 小于 最小块大小
                    _this.limit = _this.minLimit; // 每次块大小则等与最小块大小
                }
                _this.end = Math.min(_this.start + _this.limit, _this.fileSize); // 对比本次上传大小 与 文件大小对比，取终止位置
                _this.formData = new FormData();
                if (_this.start == 0 && _this.end == _this.fileSize) { // 如果文件的起止点和文件大小一样，则不需要拆分
                    _this.formData.set('file', file);
                } else {
                    _this.formData.set('file', file.slice(_this.start, _this.end)); // 拆分块
                }
                _this.formData.set('filename', file.name);
                _this.formData.set('start', _this.start);
                _this.formData.set('end', _this.end);
                _this.formData.set('size', _this.fileSize);
            }
            if (datetime - lasttimestamp < _this.failtimeout) { // 根据时间戳的差 小于失败超时时间 超时时间
                if (_this.param[1] && _this.end >= _this.fileSize) {
                    for (let key in _this.param[1]) {
                        _this.formData.set(key, _this.param[1][key]);
                    }
                } // 目前还是token
                timestamp = datetime; // 设置时间戳
                if (_this.beforeFun) { // 上传之前函数设置token
                    _this.beforeFun(_this);
                }
                JQuery.ajax({
                    url: _this.url[1],
                    type: 'POST',
                    data: _this.formData,
                    dataType: "json",
                    processData: false,
                    contentType: false,
                    success: function(responseText) {
                        _this.response = responseText;
                        try {
                            if (_this.getUploadFlag(responseText) == _this.successCode) { // 查看状态码是不是 1，是1则为成功
                                senderror = false; // 发送失败为否，默认为成功
                                if (finishSize + _this.limit >= _this.fileSize) {
                                    finishSize = _this.fileSize;
                                } else {
                                    finishSize += _this.limit; // finishSize = finishSize + _this.limit
                                }
                                _this.executeTime = Date.now() - timestamp; // 本地上传执行时间
                                if (_this.successFun) { // 执行成功回调，例如调取接口等等
                                    _this.successFun(_this);
                                }
                                if (_this.autoSpeed) { // 自动计算文件块大小
                                    if (_this.executeTime < _this.waitTime * 0.9 || _this.executeTime > _this.waitTime * 1.1) { // 上传执行时间是否在合理范围内
                                        _this.limit = parseInt((_this.end - _this.start) * _this.waitTime / _this.executeTime); // 如果在就自动计算文件块大小
                                    }
                                }
                                if (_this.fileSize <= _this.end) {
                                    finish = true;
                                } else {
                                    _this.start = _this.end;
                                }
                            } else {
                                senderror = true;
                            }
                        } catch (e) {
                            senderror = true;
                        }
                        if (responseText.state.code === 10001) {
                            uploadError = true;
                            finish = true;
                        }
                        state = true;
                    },
                    error: function(responseText) {
                        state = true;
                        senderror = true;
                    }
                });
            } else {
                state = true; // 状态
                _this.stop(); // 停止
            }
        } else {
            //console.log('没空');
        }
    }
};

let queue = {
    TaskQueue: TaskQueue,
    MultiPartUpload: MultiPartUpload
};

export default queue;